package com.galaxy.service.service.system.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.galaxy.commom.base.exception.RequestException;
import com.galaxy.service.dto.system.role.RoleAddDto;
import com.galaxy.service.dto.system.role.QueryRoleDto;
import com.galaxy.service.dto.system.role.RoleUpdateDto;
import com.galaxy.service.entity.system.Permission;
import com.galaxy.service.entity.system.Role;
import com.galaxy.service.entity.system.RolePermission;
import com.galaxy.service.entity.system.UserRole;
import com.galaxy.service.mapper.system.RoleMapper;
import com.galaxy.service.service.global.ShiroService;
import com.galaxy.service.service.system.RolePermissionService;
import com.galaxy.service.service.system.RoleService;
import com.galaxy.service.service.system.UserRoleService;
import com.google.common.collect.Lists;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 角色服务类
 * @author caijinbang
 * @date 2018/10/27 19:14
 */
@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper,Role> implements RoleService {

  @Autowired
  private RolePermissionService rolePermissionService;

  @Autowired
  private UserRoleService userRoleService;

  @Autowired
  private ShiroService shiroService;

  /**
   * 根据用户id查询所有角色
   * @param uid 用户ID
   * @param hasResource
   * @return
   */
  @Override
  public List<Role> findAllRoleByUserId(String uid,Boolean hasResource) {
    List<UserRole> userRoles = userRoleService.selectList(new EntityWrapper<UserRole>().eq("user_id", uid));
    List<Role> roles = Lists.newArrayList();
    userRoles.forEach(v->{
      Role role = this.selectById(v.getRoleId());
      if(role!=null){
        if(hasResource){
          List<Permission> permissions = rolePermissionService.findAllResourceByRoleId(role.getId());
          role.setPermissions(permissions);
        }
      }
      roles.add(role);
    });
    return roles;
  }

  /**
   * 查询服务列表
   * @param queryRoleDto
   * @return
   */
  @Override
  public Page<Role> list(QueryRoleDto queryRoleDto) {
    EntityWrapper<Role> wrapper = new EntityWrapper<>();
    wrapper.orderBy("id",queryRoleDto.getAsc());
    Page<Role> rolePage = this.selectPage(new Page<>(queryRoleDto.getPage(),
        queryRoleDto.getPageSize()), wrapper);
    if(queryRoleDto.getHasPermission()){
      if(rolePage.getRecords()!=null){
        rolePage.getRecords().forEach(v->
            v.setPermissions(rolePermissionService.findAllResourceByRoleId(v.getId())));
      }
    }
    return rolePage;
  }

  /**
   * 根据角色id移除角色
   * @param rid
   */
  @Override
  public void remove(String rid) {
    Role role = this.selectById(rid);
    if(role==null){
      throw RequestException.fail("角色不存在！");
    }
    try {
      this.deleteById(rid);
      //this.updateCache(role,true,false);
    }catch (DataIntegrityViolationException e){
      throw RequestException.fail(
          String.format("请先解除角色为 %s 角色的全部用户！",role.getName()),e);
    }catch (Exception e){
      throw RequestException.fail("角色删除失败！",e);
    }
  }

  /**
   * 更新角色
   * @param roleId 角色id
   * @param roleUpdateDto 角色更新Dto
   */
  @Override
  @Transactional(rollbackFor = Exception.class)
  public void update(String roleId, RoleUpdateDto roleUpdateDto) {
    Role role = this.selectById(roleId);
    if(role==null) {
      throw RequestException.fail("角色不存在！");
    }
    BeanUtils.copyProperties(roleUpdateDto,role);
    try {
      this.updateById(role);
      rolePermissionService.delete(new EntityWrapper<RolePermission>().eq("role_id",roleId));

      for (Permission permission : roleUpdateDto.getResources()) {
        rolePermissionService.insert(RolePermission.builder().permissionId(permission.getId()).roleId(role.getId()).build());
      }
      //this.updateCache(role,true,false);
    }catch (Exception e){
      throw RequestException.fail("角色更新失败！",e);
    }

  }

  @Override
  public void add(RoleAddDto roleAddDto) {
    Role role = this.selectOne(new EntityWrapper<Role>().eq("name", roleAddDto.getName()));
    if(role!=null){
      throw RequestException.fail(
          String.format("已经存在名称为 %s 的角色", roleAddDto.getName()));
    }
    role = new Role();
    BeanUtils.copyProperties(roleAddDto,role);
    try {
      this.insert(role);
      for (Permission permission : roleAddDto.getPermissions()) {
        rolePermissionService.insert(RolePermission.builder().permissionId(permission.getId()).roleId(role.getId()).build());
      }
    }catch (Exception e){
      throw RequestException.fail("添加失败",e);
    }
  }

  /**
   * 更新缓存
   * @param role 角色
   * @param author 是否清空授权信息
   * @param out 是否清空session
   */
  @Override
  public void updateCache(Role role,Boolean author, Boolean out) {
    List<UserRole> sysUserRoles = userRoleService.selectList(new EntityWrapper<UserRole>().eq("role_Id", role.getId()));
    List<String> userIdList = new ArrayList<>();
    if(sysUserRoles!=null && sysUserRoles.size()>0){
      sysUserRoles.forEach(v-> userIdList.add(v.getUserId()));
    }
    shiroService.clearAuthByUserIdCollection(userIdList,author,out);
  }
}
